import React, { useState, useEffect } from 'react';
import { Button } from "./ui/button";
import { useLanguage } from "~/lib/LanguageContext";
import { FolderIcon, DocumentIcon, ChevronRightIcon } from '@heroicons/react/24/outline';
import CodeViewer from './code-viewer';
import { Dialog, DialogContent, DialogTitle } from "./ui/dialog";

interface DirectoryItem {
  name: string;
  path: string;
  type: 'dir' | 'file';
  url: string;
}

interface DirectoryViewerProps {
  dirUrl: string;
  onClose?: () => void;
  repoUrl?: string;
}

export default function DirectoryViewer({ dirUrl, onClose, repoUrl }: DirectoryViewerProps) {
  const { t } = useLanguage();
  const [items, setItems] = useState<DirectoryItem[]>([]);
  const [loading, setLoading] = useState<boolean>(true);
  const [error, setError] = useState<string>('');
  const [currentPath, setCurrentPath] = useState<string>('');
  const [breadcrumbs, setBreadcrumbs] = useState<{name: string, path: string}[]>([]);
  const [selectedFileUrl, setSelectedFileUrl] = useState<string | null>(null);
  const [isCodeViewerOpen, setIsCodeViewerOpen] = useState<boolean>(false);
  
  useEffect(() => {
    // 从GitHub获取目录内容
    async function fetchDirectoryContents() {
      // 当URL为空时不执行
      if (!dirUrl) {
        setLoading(false);
        setError('未指定目录URL');
        return;
      }
      
      try {
        setLoading(true);
        
        // 把GitHub网页URL转换为API URL
        // 例如：https://github.com/username/repo/tree/master/path/to/dir
        // 变为：https://api.github.com/repos/username/repo/contents/path/to/dir
        
        // 从URL中提取用户名、仓库名和目录路径
        const githubRegex = /github\.com\/([^/]+)\/([^/]+)\/tree\/([^/]+)\/?(.*)/;
        const match = dirUrl.match(githubRegex);
        
        if (!match) {
          throw new Error('无效的GitHub目录URL');
        }
        
        const [, username, repo, branch, dirPath] = match;
        const apiUrl = `https://api.github.com/repos/${username}/${repo}/contents/${dirPath || ''}?ref=${branch}`;
        
        // 更新当前路径和面包屑
        setCurrentPath(dirPath || '');
        
        // 更新面包屑
        const pathSegments = dirPath ? dirPath.split('/') : [];
        const newBreadcrumbs = pathSegments.map((segment, index) => {
          const path = pathSegments.slice(0, index + 1).join('/');
          return { name: segment, path };
        });
        
        if (newBreadcrumbs.length === 0) {
          // 如果是根目录，添加一个根面包屑
          newBreadcrumbs.push({ name: repo || 'root', path: '' });
        }
        
        setBreadcrumbs(newBreadcrumbs);
        
        // 检查是否有GitHub PAT
        const githubPat = localStorage.getItem('github_pat');
        const headers: HeadersInit = {};
        
        if (githubPat) {
          headers.Authorization = `token ${githubPat}`;
        }
        
        const response = await fetch(apiUrl, { headers });
        
        if (!response.ok) {
          throw new Error(`获取目录内容失败: ${response.status} ${response.statusText}`);
        }
        
        const data = await response.json();
        
        // 处理目录内容
        const directoryItems: DirectoryItem[] = data.map((item: any) => ({
          name: item.name,
          path: item.path,
          type: item.type === 'dir' ? 'dir' : 'file',
          url: item.html_url
        }));
        
        // 按类型和名称排序：先目录后文件，每组内按名称字母排序
        directoryItems.sort((a, b) => {
          if (a.type === b.type) {
            return a.name.localeCompare(b.name);
          }
          return a.type === 'dir' ? -1 : 1;
        });
        
        setItems(directoryItems);
      } catch (err) {
        console.error('获取目录内容出错:', err);
        setError(err instanceof Error ? err.message : '获取目录内容时出错');
      } finally {
        setLoading(false);
      }
    }
    
    void fetchDirectoryContents();
  }, [dirUrl]);
  
  // 处理目录项点击
  const handleItemClick = (item: DirectoryItem) => {
    if (item.type === 'dir') {
      // 构建新的目录URL并加载
      const baseUrl = dirUrl.replace(/\/tree\/[^/]+\/.*$/, '');
      const branchMatch = dirUrl.match(/\/tree\/([^/]+)/);
      const branch = branchMatch ? branchMatch[1] : 'main';
      const newDirUrl = `${baseUrl}/tree/${branch}/${item.path}`;
      
      // 直接更新当前组件的状态，不需要关闭和重新打开对话框
      setLoading(true);
      setItems([]);
      setError('');
      
      // 不再调用history.replaceState，直接使用相对路径
      
      // 手动触发加载
      fetch(`https://api.github.com/repos/${(newDirUrl.split('/')[3] || '')}/${(newDirUrl.split('/')[4] || '')}/contents/${item.path}`)
        .then(response => response.json())
        .then(data => {
          const directoryItems: DirectoryItem[] = data.map((item: any) => ({
            name: item.name,
            path: item.path,
            type: item.type === 'dir' ? 'dir' : 'file',
            url: item.html_url
          }));
          
          // 按类型和名称排序
          directoryItems.sort((a, b) => {
            if (a.type === b.type) {
              return a.name.localeCompare(b.name);
            }
            return a.type === 'dir' ? -1 : 1;
          });
          
          setItems(directoryItems);
          setCurrentPath(item.path);
          
          // 更新面包屑
          const pathSegments = item.path.split('/');
          const newBreadcrumbs = pathSegments.map((segment, index) => {
            const path = pathSegments.slice(0, index + 1).join('/');
            return { name: segment, path };
          });
          setBreadcrumbs(newBreadcrumbs);
        })
        .catch(err => {
          console.error('获取目录内容出错:', err);
          setError(err instanceof Error ? err.message : '获取目录内容时出错');
        })
        .finally(() => {
          setLoading(false);
        });
    } else {
      // 对于文件，打开代码查看器
      setSelectedFileUrl(item.url);
      setIsCodeViewerOpen(true);
    }
  };
  
  // 处理面包屑导航
  const handleBreadcrumbClick = (breadcrumb: {name: string, path: string}) => {
    if (breadcrumb.path === currentPath) return;
    
    // 构建新的目录URL并加载
    const baseUrl = dirUrl.replace(/\/tree\/[^/]+\/.*$/, '');
    const branchMatch = dirUrl.match(/\/tree\/([^/]+)/);
    const branch = branchMatch ? branchMatch[1] : 'main';
    const newPath = breadcrumb.path || '';
    const newDirUrl = `${baseUrl}/tree/${branch}/${newPath}`;
    
    // 不再调用history.replaceState
    
    // 手动触发加载
    setLoading(true);
    setItems([]);
    setError('');
    
    const apiPath = newPath ? `/${newPath}` : '';
    const apiUrl = `https://api.github.com/repos/${(baseUrl.split('/')[3] || '')}/${(baseUrl.split('/')[4] || '')}/contents${apiPath}`;
    
    fetch(apiUrl)
      .then(response => response.json())
      .then(data => {
        const directoryItems: DirectoryItem[] = data.map((item: any) => ({
          name: item.name,
          path: item.path,
          type: item.type === 'dir' ? 'dir' : 'file',
          url: item.html_url
        }));
        
        // 按类型和名称排序
        directoryItems.sort((a, b) => {
          if (a.type === b.type) {
            return a.name.localeCompare(b.name);
          }
          return a.type === 'dir' ? -1 : 1;
        });
        
        setItems(directoryItems);
        setCurrentPath(newPath);
        
        // 更新面包屑
        const pathSegments = newPath ? newPath.split('/') : [];
        const newBreadcrumbs = pathSegments.map((segment, index) => {
          const path = pathSegments.slice(0, index + 1).join('/');
          return { name: segment, path };
        });
        
        if (newBreadcrumbs.length === 0) {
          // 如果是根目录，添加一个根面包屑
          newBreadcrumbs.push({ name: repoUrl?.split('/').pop() || 'root', path: '' });
        }
        
        setBreadcrumbs(newBreadcrumbs);
      })
      .catch(err => {
        console.error('获取目录内容出错:', err);
        setError(err instanceof Error ? err.message : '获取目录内容时出错');
      })
      .finally(() => {
        setLoading(false);
      });
  };
  
  return (
    <div className="flex flex-col w-full h-full border-2 border-gray-200 rounded-lg bg-white dark:bg-gray-900 dark:border-gray-700 shadow-lg">
      <div className="flex justify-between items-center border-b p-4 dark:border-gray-700">
        <h3 className="font-semibold text-lg truncate flex-1">
          {t("directory_browser")}
        </h3>
        {onClose && (
          <button 
            onClick={onClose}
            className="ml-2 text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"
          >
            ✕
          </button>
        )}
      </div>
      
      {/* 面包屑导航 */}
      <div className="border-b p-2 flex flex-wrap items-center dark:border-gray-700">
        <button 
          onClick={() => handleBreadcrumbClick({name: 'Root', path: ''})}
          className="px-2 py-1 text-sm text-gray-600 hover:bg-gray-100 rounded dark:text-gray-300 dark:hover:bg-gray-800"
        >
          {repoUrl?.split('/').pop() || 'Root'}
        </button>
        {breadcrumbs.length > 0 && breadcrumbs.map((item, index) => (
          <React.Fragment key={index}>
            <ChevronRightIcon className="h-4 w-4 text-gray-400 mx-1" />
            <button 
              onClick={() => handleBreadcrumbClick(item)}
              className={`px-2 py-1 text-sm rounded ${
                index === breadcrumbs.length - 1 
                  ? 'font-medium text-blue-600 dark:text-blue-400' 
                  : 'text-gray-600 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-800'
              }`}
            >
              {item.name}
            </button>
          </React.Fragment>
        ))}
      </div>
      
      {/* 目录内容 */}
      <div className="flex-1 overflow-auto">
        {loading ? (
          <div className="flex justify-center items-center h-full p-4">
            <div className="w-8 h-8 border-4 border-blue-400 border-t-transparent rounded-full animate-spin"></div>
          </div>
        ) : error ? (
          <div className="flex justify-center items-center h-full p-4 text-red-500">
            {error}
          </div>
        ) : items.length === 0 ? (
          <div className="flex justify-center items-center h-full p-4 text-gray-500">
            {t("empty_directory")}
          </div>
        ) : (
          <ul className="divide-y dark:divide-gray-700">
            {items.map((item, index) => (
              <li key={index}>
                <button
                  onClick={() => handleItemClick(item)}
                  className="w-full px-4 py-3 flex items-center hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors text-left"
                >
                  {item.type === 'dir' ? (
                    <FolderIcon className="h-5 w-5 text-yellow-500 mr-3 flex-shrink-0" />
                  ) : (
                    <DocumentIcon className="h-5 w-5 text-blue-500 mr-3 flex-shrink-0" />
                  )}
                  <span className="truncate">{item.name}</span>
                </button>
              </li>
            ))}
          </ul>
        )}
      </div>
      
      {/* 代码查看器对话框 */}
      <Dialog open={isCodeViewerOpen} onOpenChange={setIsCodeViewerOpen}>
        <DialogContent className="max-w-6xl h-[90vh] p-0 m-2">
          <DialogTitle className="sr-only">文件内容查看器</DialogTitle>
          {selectedFileUrl && (
            <CodeViewer 
              fileUrl={selectedFileUrl} 
              onClose={() => setIsCodeViewerOpen(false)}
              repoUrl={repoUrl}
            />
          )}
        </DialogContent>
      </Dialog>
    </div>
  );
} 